/**
 * 统一错误处理工具
 * 
 * 提供标准化的API错误响应格式和处理函数
 */

import { NextResponse } from 'next/server';
import { ZodError } from 'zod';

// API错误类型
export type ApiErrorType = 
  | 'VALIDATION_ERROR'  // 数据验证错误
  | 'AUTHENTICATION_ERROR' // 认证错误
  | 'AUTHORIZATION_ERROR' // 授权错误
  | 'NOT_FOUND_ERROR' // 资源不存在
  | 'CONFLICT_ERROR' // 资源冲突
  | 'DATABASE_ERROR' // 数据库错误
  | 'EXTERNAL_SERVICE_ERROR' // 外部服务错误
  | 'RATE_LIMIT_ERROR' // 速率限制错误
  | 'INTERNAL_SERVER_ERROR'; // 服务器内部错误

// API错误接口
export interface ApiErrorResponse {
  success: false;
  message: string;
  error: {
    type: ApiErrorType;
    code?: string;
    details?: any;
  }
  statusCode: number;
}

// API成功接口
export interface ApiSuccessResponse<T = any> {
  success: true;
  message?: string;
  data?: T;
}

// 错误状态码映射
const errorStatusCodes: Record<ApiErrorType, number> = {
  VALIDATION_ERROR: 400,
  AUTHENTICATION_ERROR: 401,
  AUTHORIZATION_ERROR: 403,
  NOT_FOUND_ERROR: 404,
  CONFLICT_ERROR: 409,
  DATABASE_ERROR: 500,
  EXTERNAL_SERVICE_ERROR: 502,
  RATE_LIMIT_ERROR: 429,
  INTERNAL_SERVER_ERROR: 500
};

/**
 * 创建错误响应
 * 
 * @param type 错误类型
 * @param message 错误消息
 * @param details 错误详情
 * @param code 自定义错误代码
 * @returns NextResponse错误响应
 */
export function createErrorResponse(
  type: ApiErrorType,
  message: string,
  details?: any,
  code?: string
): NextResponse<ApiErrorResponse> {
  const statusCode = errorStatusCodes[type] || 500;
  
  const errorResponse: ApiErrorResponse = {
    success: false,
    message,
    error: {
      type,
      ...(code ? { code } : {}),
      ...(details ? { details } : {})
    },
    statusCode
  };
  
  console.error(`API错误: [${type}] ${message}`, details || '');
  
  return NextResponse.json(errorResponse, { status: statusCode });
}

/**
 * 创建成功响应
 * 
 * @param data 响应数据
 * @param message 成功消息
 * @returns NextResponse成功响应
 */
export function createSuccessResponse<T = any>(
  data?: T,
  message?: string
): NextResponse<ApiSuccessResponse<T>> {
  return NextResponse.json({
    success: true,
    ...(message ? { message } : {}),
    ...(data !== undefined ? { data } : {})
  });
}

/**
 * 处理API异常
 * 
 * @param error 捕获的错误
 * @returns 格式化的错误响应
 */
export function handleApiError(error: unknown): NextResponse<ApiErrorResponse> {
  console.error('API错误:', error);
  
  // Zod验证错误
  if (error instanceof ZodError) {
    return createErrorResponse(
      'VALIDATION_ERROR',
      '输入数据验证失败',
      error.errors
    );
  }
  
  // Prisma错误
  if (error instanceof Error && error.name === 'PrismaClientKnownRequestError') {
    // @ts-ignore - Prisma错误特有属性
    const code = error.code;
    let type: ApiErrorType = 'DATABASE_ERROR';
    let message = '数据库操作失败';
    
    // 处理常见的Prisma错误码
    if (code === 'P2002') {
      type = 'CONFLICT_ERROR';
      message = '数据唯一性冲突';
    } else if (code === 'P2025') {
      type = 'NOT_FOUND_ERROR';
      message = '请求的记录不存在';
    }
    
    return createErrorResponse(type, message, { prismaCode: code });
  }
  
  // 常规错误对象
  if (error instanceof Error) {
    return createErrorResponse(
      'INTERNAL_SERVER_ERROR',
      error.message || '服务器内部错误'
    );
  }
  
  // 未知错误类型
  return createErrorResponse(
    'INTERNAL_SERVER_ERROR',
    '发生未知错误',
    { originalError: String(error) }
  );
}

/**
 * API请求处理包装器
 * 自动处理常见错误并返回标准响应格式
 * 
 * @param handler API请求处理函数
 * @returns 包装后的处理函数
 */
export function withErrorHandling<T = any>(
  handler: () => Promise<T>
): Promise<NextResponse> {
  return handler()
    .then(data => createSuccessResponse(data))
    .catch(error => handleApiError(error));
} 